package process

import (
	"encoding/json"
	"errors"
	"fmt"
	"helloword01/31chatroom/common/db/userDao"
	commonmodel "helloword01/31chatroom/common/model"
	"helloword01/31chatroom/common/utils"
	"net"
)

type UserProcess struct {
	Conn   net.Conn
	UserId int
}

func (this *UserProcess) ServerProcessLogin(mes *commonmodel.Message) (err error) {
	//1.接收登录消息
	var loginMes commonmodel.LoginMes
	err = json.Unmarshal([]byte(mes.Data), &loginMes)
	if err != nil {
		return errors.New("json反序列化失败")
	}
	//fmt.Println("server#Login-收到：", loginMes)
	//2.调用userDao的Login方法
	_, err = userDao.MyUserDao.Login(loginMes.UserId, loginMes.UserPwd)

	//3.构建-返回消息体:message.LoginResMes
	var loginResMes commonmodel.LoginResMes
	if err != nil {
		if errors.Is(err, commonmodel.ErrorUserNotExists) {
			loginResMes.Code = 500
			loginResMes.Error = err.Error()
		} else if errors.Is(err, commonmodel.ErrorUserPwd) {
			loginResMes.Code = 403
			loginResMes.Error = err.Error()
		} else {
			loginResMes.Code = 500
			loginResMes.Error = "server internal error"
		}
	} else {
		//3.1登录成功~
		loginResMes.Code = 200

		//3.2将当前process添加到用户管理器
		this.UserId = loginMes.UserId
		MyUserMgr.AddOnlineUser(this)
		users := MyUserMgr.GetAllOnlineUser()

		//3.3.返回在线用户ids
		for id, _ := range users {
			loginResMes.UsersId = append(loginResMes.UsersId, id)
		}
		//3.4通知通知所有人，有用户上线
		this.NotifyOthersOnlineUser(loginMes.UserId)
	}

	data, err := json.Marshal(loginResMes)
	if err != nil {
		return errors.New("json序列化失败")
	}

	//4.构建登录返回的消息体
	res, err := utils.BuildMessage(data, commonmodel.LonginResMesType)
	if err != nil {
		return errors.New(err.Error())
	}

	trans := &utils.Transfer{
		Conn: this.Conn,
	}

	//5.发送登录结果消息
	return trans.WritePkg(res)

}

// ServerProcessRegister
//
//	@Description: 处理用户注册消息
//	@receiver this
//	@param mes
//	@return err
func (this *UserProcess) ServerProcessRegister(mes *commonmodel.Message) (err error) {
	//1.读取注册消息
	var registerMes commonmodel.RegisterMes
	err = json.Unmarshal([]byte(mes.Data), &registerMes)
	if err != nil {
		return errors.New("json反序列化失败")
	}

	//fmt.Println("server#Register-收到：", registerMes)
	//2.执行注册（redis）
	err = userDao.MyUserDao.Register(&registerMes.User)
	//3.构建注册结果消息体
	var registerResMes commonmodel.RegisterResMes
	if err != nil {
		if errors.Is(err, commonmodel.ErrorUserExists) {
			registerResMes.Code = 500
			registerResMes.Error = err.Error()
		} else {
			registerResMes.Code = 500
			registerResMes.Error = "server internal error"
		}
	} else {
		registerResMes.Code = 200
	}
	data, err := json.Marshal(registerResMes)
	if err != nil {
		return errors.New("json序列化失败")
	}

	//4.构建通用消息体
	res, err := utils.BuildMessage(data, commonmodel.RegisterResMesType)
	if err != nil {
		return errors.New(err.Error())
	}

	//5.发送注册结果消息
	trans := &utils.Transfer{
		Conn: this.Conn,
	}
	//fmt.Println("server#Register-发送：", string(res))
	return trans.WritePkg(res)

}

// NotifyOthersOnlineUser
//
//	@Description: 通知其他用户，有用户上线
//	@receiver this
//	@param userId
func (this *UserProcess) NotifyOthersOnlineUser(userId int) {
	users := MyUserMgr.GetAllOnlineUser()
	for id, up := range users {
		if id == userId { // 排除当前连接的用户
			continue
		}
		//通知别人，我上线了
		up.NotifyMeOnline(userId)
	}
}

// NotifyMeOnline
//
//	@Description: 发送用户上线的消息
//	@receiver this
//	@param userId
func (this *UserProcess) NotifyMeOnline(userId int) {
	//1.构建消息体
	var notifyUserStatusMes commonmodel.NotifyUserStatusMes
	notifyUserStatusMes.UserId = userId
	notifyUserStatusMes.Status = commonmodel.UserOnline
	data, err := json.Marshal(notifyUserStatusMes)
	if err != nil {
		fmt.Println("Marshal err=", err)
		return
	}
	data, err = utils.BuildMessage(data, commonmodel.NotifyUserStatusMesType)
	if err != nil {
		fmt.Println("Marshal err=", err)
		return
	}
	tf := &utils.Transfer{
		Conn: this.Conn,
	}
	// 2.发送用户上线的消息
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("WritePkg err=", err)
		return
	}
}
